#include "server.h"

extern MYSQL* mySql;

//删除文件或目录
int RmFile(char* Filename, int userId) {
    //获取该文件或目录的id
    int fileId;
    int retVal = PathnameAnalyse(Filename, userId, &fileId);
    if(retVal == WRONG_PATHNAME) {
        //如果路径错误则直接返回
        return -1;
    } else {
        //如果路径正确则递归删除该文件
        int ret = RecursiveDelete(fileId);
        if(ret == -1) {
            return -1;
        }
        return 0;
    }
}

//判断是否还有其他用户，或该用户是否有其他目录项指向该文件，如果有，则不必删除物理文件
int OthersLinked(char* md5) {
    //根据传入的md5码查找md5码相同的文件有多少
    char querySentence[2048] = {0};
    sprintf(querySentence, "select count(id) from filesystem where md5 = '%s'", md5);
    int ret = mysql_query(mySql, querySentence);
    if(ret != 0) {
        printf("query error: %s\n", mysql_error(mySql));
        return -1;
    }
    MYSQL_RES* result = mysql_store_result(mySql);
    if(result == NULL) {
        printf("query error: %s\n", mysql_error(mySql));
        return -1;
    }
    MYSQL_ROW row = mysql_fetch_row(result);
    int count = atoi(row[0]);
    mysql_free_result(result);
    //如果md5码相同的文件个数大于1，则不从物理磁盘中删除文件
    if(count > 1) {
        return 1;
    } else {
        return 0;
    }

}

//删除文件或目录
int DeleteFileOrDir(int fileId) {
    char md5[1024] = {0};
    char querySentence[2048] = {0};
    //先根据id找出md5码
    sprintf(querySentence, "select md5 from filesystem where id = %d", fileId);
    int ret = mysql_query(mySql, querySentence);
    if(ret != 0) {
        printf("query error: %s\n", mysql_error(mySql));
        return -1;
    }
    MYSQL_RES* result = mysql_store_result(mySql);
    if(result == NULL) {
        printf("query error: %s\n", mysql_error(mySql));
        return -1;
    }
    MYSQL_ROW row = mysql_fetch_row(result);
    memset(md5, 0, sizeof(md5));
    strcpy(md5, row[0]);
    mysql_free_result(result);
    //如果md5为NULL则该文件为目录文件，直接删除目录项然后返回
    if(strcmp(md5, "0") == 0) {
        memset(querySentence, 0, sizeof(querySentence));
        sprintf(querySentence, "delete from filesystem where id = %d", fileId);
        ret = mysql_query(mySql, querySentence);
        if(ret != 0) {
            printf("query error: %s\n", mysql_error(mySql));
            return -1;
        }
        return 0;
    }
    //若md5码不为NULL则该文件为普通文件，开始查找是否有其他连接到此文件的目录项
    int moreThanOne = OthersLinked(md5);
    if(moreThanOne == -1) {
        //如果OthersLinked函数返回-1，表明查找失败，直接返回
        return -1;
    } else if(moreThanOne == 0) {
        //如果OthersLinked返回0，表明除该目录项之外没有其他指向该文件的目录项，直接删除该物理文件
        ret = unlink(md5);
        if(ret == -1) {
            return -1;
        }
    }
    //如果OthersLinked返回1，则不必删除物理文件，删除目录项即可
    memset(querySentence, 0, sizeof(querySentence));
    sprintf(querySentence, "delete from filesystem where id = %d", fileId);
    ret = mysql_query(mySql, querySentence);
    if(ret != 0) {
        printf("query error: %s\n", mysql_error(mySql));
        return -1;
    }
    return 0;
}

int RecursiveDelete(int fileId) {
    char querySentence[2048] = {0};
    int rowCount;
    int id[1024] = {0};
    //找出以该fileId为parent_id的文件，然后递归调用函数删除这些文件
    sprintf(querySentence, "select id from filesystem where parent_id = %d", fileId);
    int ret = mysql_query(mySql, querySentence);
    if(ret != 0) {
        printf("query error: %s\n", mysql_error(mySql));
        return -1;
    }
    MYSQL_RES* result = mysql_store_result(mySql);
    if(result == NULL) {
        printf("query error: %s\n", mysql_error(mySql));
        return -1;
    }
    rowCount = mysql_num_rows(result);
    MYSQL_ROW row; 
    for(int i = 0; i < rowCount; i++) {
        row = mysql_fetch_row(result);
        id[i] = atoi(row[0]);
    }
    mysql_free_result(result);
    //开始递归删除
    for(int i = 0; i < rowCount; i++) {
        ret = RecursiveDelete(id[i]);
        if(ret == -1) {
            return -1;
        }
    }
    ret = DeleteFileOrDir(fileId);
    if(ret == 0) {
        return 0;
    } else {
        return -1;
    }
}


